论坛首页 Web前端技术论坛

DWR使用初探

浏览 16174 次
锁定老帖子 主题:DWR使用初探
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2005-11-04  
DWR
不知道发到那个版好。DWR大家都知道吧。scud的webwork2.2
新特性里面有说到过。不过我没有用webwork2.2
我只是在项目中使用了。DWR做一些Ajax的应用。
想了解更多请看这里 DWR官方网站

   我选择DWR的原因是因为DWR可以很好的和Spring集成。下面我们用它来做一个小应用。也在我的项目中用到了。就是选择大类别的时候取小类别更新到select

   DWR的文档也很详细,第一步要再你的web.xml配置一个servlet.

	<servlet>
		<servlet-name>dwr-invoker</servlet-name>
		<display-name>DWR Servlet</display-name>
		<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
		<init-param>
			<param-name>debug</param-name>
			<param-value>true</param-value>
		</init-param>
	</servlet>
	<servlet-mapping>
		<servlet-name>dwr-invoker</servlet-name>
		<url-pattern>/dwr/*</url-pattern>
	</servlet-mapping>

  debug很有用在开发的时候建议还是用true.

下面在你的WEB-INF下增加一个dwr.xml文件.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd">

<dwr>
<allow>
<!--通用的根据itemType来取ListItem-->
<create creator="spring" javascript="listItemUtil">
<param name="beanName" value="listItemManagerDwr"/>
<include method="getListItemsByType"/>
</create>

<convert converter="bean" match="cn.jdk.leaf.entity.wrapper.LiteralListItem"/>
</allow>
</dwr>

这个文件也很简单还有dtd文件.
我们项目用的是webwork+spring+hibernate所以这里creator就是spring

beanName就是spring中配置的bean的id <include method>
可以不用配置,这里把getListItemsByType方法提供给dwr Remote call.

下面一个converter 就是getListItemsByType方法返回的List对象

    private String itemId;
    
    private String itemValue;

    public String getItemId(); {
        return itemId;
    }

    public void setItemId(String itemId); {
        this.itemId = itemId;
    }

    public String getItemValue(); {
        return itemValue;
    }

    public void setItemValue(String itemValue); {
        this.itemValue = itemValue;
    }
   发表时间:2005-11-04  
getListItemsByType方法,就是传递一个大类别的id,然后去取小类别.
    public List getListItemsByType(int type); {
        return listItemManager.wrap(itemMapUtil.getListItems(type););;
    }


这里做了一下包装.只取其中的id和name,我只需要这个两个就够了.
包装方法:
    public List wrap(List items); {
        List wrapItems = new ArrayList();;
        for(int i=0;i<items.size();;i++);{
            LiteralListItem lItem = new LiteralListItem();;
            ListItem item = (ListItem);items.get(i);;
            lItem.setItemId(item.getItemId(););;
            lItem.setItemValue(item.getItemValue(););;
            wrapItems.add(lItem);;
        }
        return wrapItems;
    }


这里后台代码就完毕了.
0 请登录后投票
   发表时间:2005-11-04  
现在启动服务,你可以通过dwr的调试来测试你的方法,记得刚才配置的那里要配置成true哦.

http://192.168.0.5/xx/dwr
你可以看到如下的界面
Classes known to DWR:
userManager ($Proxy82)
favourites ($Proxy80)
folderManager ($Proxy83)
deliverItemManager ($Proxy84)
listItemUtil ($Proxy81)
Other Links
Up to top level of web app.



看到我们刚才配置的listItemUtil了么.恭喜你成功了.我们来测试一下方法.点一下
listItemUtil($Proxy81)
你将看到:


Methods For: listItemUtil ($Proxy81)
To use this class in your javascript you will need the following script includes:

  &lt;script type='text/javascript' src='/trizlink/dwr/interface/listItemUtil.js'&gt;&lt;/script&gt;
  &lt;script type='text/javascript' src='/trizlink/dwr/engine.js'&gt;&lt;/script&gt;

In addition there is an optional utility script:

  &lt;script type='text/javascript' src='/trizlink/dwr/util.js'&gt;&lt;/script&gt;

Replies from DWR are shown with a yellow background if they are simple or in an alert box otherwise.
The inputs are evaluated as Javascript so strings must be quoted before execution.

There are 33 declared methods:

hashCode() is not available: Method access is denied by rules in dwr.xml
equals() is not available: Method access is denied by rules in dwr.xml
toString() is not available: Method access is denied by rules in dwr.xml
indexOf() is not available: Method access is denied by rules in dwr.xml
getListItemsByType(  ); 
addAdvisor() is not available: Method access is denied by rules in dwr.xml
addAdvisor() is not available: Method access is denied by rules in dwr.xml
setTargetSource() is not available: Method access is denied by rules in dwr.xml
isProxyTargetClass() is not available: Method access is denied by rules in dwr.xml
setExposeProxy() is not available: Method access is denied by rules in dwr.xml
isExposeProxy() is not available: Method access is denied by rules in dwr.xml
isFrozen() is not available: Method access is denied by rules in dwr.xml
getProxiedInterfaces() is not available: Method access is denied by rules in dwr.xml
addAdvice() is not available: Method access is denied by rules in dwr.xml
addAdvice() is not available: Method access is denied by rules in dwr.xml
getTargetSource() is not available: Method access is denied by rules in dwr.xml
isInterfaceProxied() is not available: Method access is denied by rules in dwr.xml
removeAdvice() is not available: Method access is denied by rules in dwr.xml
removeAdvisor() is not available: Method access is denied by rules in dwr.xml
removeAdvisor() is not available: Method access is denied by rules in dwr.xml
getAdvisors() is not available: Method access is denied by rules in dwr.xml
replaceAdvisor() is not available: Method access is denied by rules in dwr.xml
toProxyConfigString() is not available: Method access is denied by rules in dwr.xml
isProxyClass() is not available: Method access is denied by rules in dwr.xml
getProxyClass() is not available: Method access is denied by rules in dwr.xml
newProxyInstance() is not available: Method access is denied by rules in dwr.xml
getInvocationHandler() is not available: Method access is denied by rules in dwr.xml
getClass() is not available: Method access is denied by rules in dwr.xml
wait() is not available: Method access is denied by rules in dwr.xml
wait() is not available: Method access is denied by rules in dwr.xml
wait() is not available: Method access is denied by rules in dwr.xml
notify() is not available: Method access is denied by rules in dwr.xml
notifyAll() is not available: Method access is denied by rules in dwr.xml
Other Links
Back to class index.
Up to top level of web app.
Fixing Issues
Warning: No Converter for XXX.
dwr.xml does not have an allow entry that enables conversion of this type to Javascript. The most common cause of this problem is that XXX is a java bean and bean marshalling has not been enabled. Bean marshalling is disabled by default for security reasons.

To enable marshalling for a given bean add the following line to the allow section of your dwr.xml file:

&lt;convert converter="bean" match="XXX"/&gt;

It is also possible to enable marshalling for an entire package or hierachy of packages using the following:

&lt;convert converter="bean" match="package.name.*"/&gt;

Warning: overloaded methods are not recommended
Javascript does not support overloaded methods, so the javascript file generated from this class will contain to methods the second of which will replace the first. This is probably not what you wanted.

It is best to avoid overloaded methods when using DWR.
0 请登录后投票
   发表时间:2005-11-04  
接下来就是页面处理了.
在需要用到这个调用的页面里面加上这两个js
  <script type='text/javascript' src='/trizlink/dwr/interface/listItemUtil.js'></script>
  <script type='text/javascript' src='/trizlink/dwr/engine.js'></script>



还有一个很有用的util.js是Joe封装的一些很有用的操作
addOptions etc. 详细看这里
我一般都把它加进来了.
In addition there is an optional utility script:

  <script type='text/javascript' src='/trizlink/dwr/util.js'></script>




然后为我们的大类别的onchange事件添加方法
//改变大类别时改变小类别
function changeType(val);{
	if(val==0);{
		DWRUtil.removeAllOptions("smallType");;
		DWRUtil.addOptions("smallType",['全部']);;
		return;
	}
	$("bigType");.disabled = true;
	listItemUtil.getListItemsByType(listItemCallback,val);;
}


注意到listItemUtil就是刚开始我们配置的creator
getListItemByType就是spring bean 里面的方法.
这里有两个参数,第一个参数就是这个方法返回的值(就是那个LiteralListItem的List)交给listItemCallback方法处理,

第二个参数 val 就是spring bean方法的参数(就是大类别的id).
var listItemCallback = function(items);{
	var sel = DWRUtil.getValue("smallType");;
	DWRUtil.removeAllOptions("smallType");;
	DWRUtil.addOptions("smallType",["全部"]);;
	DWRUtil.addOptions("smallType",items,"itemId","itemValue");;
	DWRUtil.setValue("smallType", sel);;
	$("bigType");.disabled = false;	
}
0 请登录后投票
   发表时间:2005-11-09  
我实现这样签名的方法,运行时会出错,大致是说在reflect操作之 Field#set(obj,value)时,出现权限异常。
公司没有环境,不能把异常贴出来。

class Person{
 String name;
 int age;
}

//里面的两个方法暴露给dwr。
class PersonService{
  //js先调用newPerson,对收到的实例的name属性赋值后,调用下面的store方法,就出了异常。
   Person newPerson();{
     return new Person();;
   }
  void store(Person person);{
    // do nothing
  }
}
0 请登录后投票
   发表时间:2005-11-10  
liusong1111 写道
我实现这样签名的方法,运行时会出错,大致是说在reflect操作之 Field#set(obj,value)时,出现权限异常。
公司没有环境,不能把异常贴出来。

class Person{
 String name;
 int age;
}

//里面的两个方法暴露给dwr。
class PersonService{
  //js先调用newPerson,对收到的实例的name属性赋值后,调用下面的store方法,就出了异常。
   Person newPerson();{
     return new Person();;
   }
  void store(Person person);{
    // do nothing
  }
}


New ObjectConverter (called 'object') that reads fields rather than bean getters and setters. Includes a 'force' parameter to read from private fields

dwr1.0必须写get set 方法.
0 请登录后投票
   发表时间:2005-11-10  
liusong1111 写道
我实现这样签名的方法,运行时会出错,大致是说在reflect操作之 Field#set(obj,value)时,出现权限异常。
公司没有环境,不能把异常贴出来。

class Person{
 String name;
 int age;
}

//里面的两个方法暴露给dwr。
class PersonService{
  //js先调用newPerson,对收到的实例的name属性赋值后,调用下面的store方法,就出了异常。
   Person newPerson();{
     return new Person();;
   }
  void store(Person person);{
    // do nothing
  }
}


你这样不可以么?
  void store(String name,int age);{
     Person p = new Person();;
     p.setName(name);;
     p.setAge(age);;
    // do nothing
  }

0 请登录后投票
   发表时间:2005-11-10  
对了。大家 帮我看看,我在修改了之后更新table,
不过最近一次都没有反应到table,再次修改就有了。
大家看看是怎么回事?

	$("btn_save");.disabled = true;
	folderManager.modifyFolder(id,name,memo);;
	folderManager.getMyFolders(folderCallback);;
	$("folderName");.value = "";
	$("folderMemo");.value = "";
	$("folderId");.value = 0;
0 请登录后投票
   发表时间:2005-11-10  
	$("btn_save");.disabled = true;
	DWREngine.beginBatch();;	
	folderManager.modifyFolder(id,name,memo);;
	folderManager.getMyFolders(folderCallback);;
	DWREngine.endBatch();;	
	$("folderName");.value = "";
	$("folderMemo");.value = "";
	$("folderId");.value = 0;


好像这个样子就可以了。一起提交。
0 请登录后投票
   发表时间:2005-11-14  
引用
folderManager.getMyFolders(folderCallback);

这行是从服务器端检索数据用来重新刷新table的吧。
是不是因为两个操作有严格的的执行顺序约束,需要在modifyFolder的callback中调用才行,或用batch达到同样的效果?

改成
void store(String name,int age); 签名,不方便应用自己写的js框架。写个js方法:
BeanUtil.fillProperties(obj); 收集form中的数据,set到指定对象的属性,然后调用store(Object obj)就可以了。

后来我改试BeanConverter居然可以了!!!先前记得是不行的
家里宽带该续费了 ~
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics